#include "TFBoard.h"
#include "TFConstants.h"
#include "TFRuleCheckerImpl.h"
#include "TFSoundManager.h"

TFRuleCheckerImpl * _ruleChecker = new TFRuleCheckerImpl();	//This is  a new instance, it needs to be passed from model.

TFBoard::TFBoard()
{
	ResetBoard();
}

TFBoard::~TFBoard()
{
}

void TFBoard::ResetBoard()
{
	for(int i=0; i < BOARD_DIMENSION; i++)
	{
		for(int j=0; j < BOARD_DIMENSION; j++)
		{
			board[i][j] = TFGamePiece();
		}
	}
}

void TFBoard::ResetBoard(TF_PLAYERS player)
{
	if (player == RED_PLAYER)
	{
		//top half
		for(int y=0; y < BOARD_DIMENSION/2; y++)
		{
			for(int x=0; x < BOARD_DIMENSION; x++)
			{
				board[y][x] = TFGamePiece();
			}
		}
	}
	else
	{
		//bottom half
		for(int y=BOARD_DIMENSION/2; y < BOARD_DIMENSION; y++)
		{
			for(int x=0; x < BOARD_DIMENSION; x++)
			{
				board[y][x] = TFGamePiece();
			}
		}
	}
}

HRESULT TFBoard::MoveTroop(TFGameTurn* myTurn, bool useRules)
{
	HRESULT HR = S_OK;

	TFRuleCheckerImpl* ruleChecker = new TFRuleCheckerImpl();
	if(!useRules || ruleChecker->LegalMove(this, myTurn, useRules)) // If Valid move
	{		
		PA_WaitForVBL();
		HRESULT HR = S_OK;
		HR = AddPiece(myTurn->GetMove()->GetX2(), myTurn->GetMove()->GetY2(), TROOP_TEMP, myTurn->GetTurn());
		//PA_OutputText(1,0,14, "Move to:%d,%d",myTurn->GetMove()->GetX2(), myTurn->GetMove()->GetY2() );
		if(HR == S_OK){
			RemovePiece(myTurn->GetMove()->GetX1(), myTurn->GetMove()->GetY1());
			
			//Carry over Troop Points
			board[myTurn->GetMove()->GetY2()][myTurn->GetMove()->GetX2()].SetPoints(board[myTurn->GetMove()->GetY1()][myTurn->GetMove()->GetX1()].GetPoints());
			//Reset points and previous spot
			board[myTurn->GetMove()->GetY1()][myTurn->GetMove()->GetX1()].SetPoints(3);
		
		}else{

		}
		
		

	}else
	{
		//PA_OutputText(1,0,11, "ELSE move----");
		//PA_WaitForVBL();
        TFSoundManager::PlaySound(SOUND_INVALID_MOVE);
	}

	return HR;
}


HRESULT TFBoard::AddPiece(int locX, int locY, TF_ADD_PIECE pieceType, TF_PLAYERS player)
{
	int row = locY;
	int col = locX;
	
	HRESULT HR = S_OK;


	if(_model->GetTurnState()== SETUP){
		if(!_ruleChecker->CanPlacePieceHere(row, col,pieceType, player, this)){
			HR = E_FAIL;
			return HR;
		}
	}else{


	}

	if(board[row][col].GetPiece() == TROOP_PIECE &&
	   board[row][col].GetColor() != player) // opposing troop 
	{
		_model->TakeTroop(true, board[row][col].GetColor());
		//play sound based on color
		if (player == RED_PLAYER)
		{
			//taking blue player
			TFSoundManager::PlaySound(SOUND_KNOCK_TROOP_BLUE);
		}
		else
		{
			//taking blue player
			TFSoundManager::PlaySound(SOUND_KNOCK_TROOP_RED);
		}
	}

	if(pieceType == BARRICADE) {
		switch(board[row][col].GetPiece())
		{
		case EMPTY:
			board[row][col].SetPiece(BARRICADE_1);
			board[row][col].SetColor(player);
			break;
		case BARRICADE_1:
			board[row][col].SetPiece(BARRICADE_2);
			board[row][col].SetColor(player);
			break;
		case BARRICADE_2:
			board[row][col].SetPiece(BARRICADE_3);
			board[row][col].SetColor(player);
			break;
		case BARRICADE_3:
			//barricade full - send error message back
			break;
		default:
			//send error message back	
			break;
		}
	}
	else if(pieceType == FLAG_FORTIFICATION || pieceType == FLAG)
	{
		
		switch(board[row][col].GetPiece())
		{
		case EMPTY:
			board[row][col].SetPiece(FLAG_0);
			board[row][col].SetColor(player);
			break;
		case FLAG_0:
			board[row][col].SetPiece(FLAG_1);
			board[row][col].SetColor(player);
			break;
		case FLAG_1:
			board[row][col].SetPiece(FLAG_2);
			board[row][col].SetColor(player);
			break;
		case FLAG_2:
			//flag fortification full - send error message back
			break;
		default:
			//send error message back	
			break;
		}	
	}
	else if(pieceType == TROOP_TEMP)
	{
		board[row][col].SetPiece(TROOP_PIECE);
		board[row][col].SetColor(player);
	}

	return HR;
}

HRESULT TFBoard::RemovePiece(int locX, int locY)
{
	int row = locY;
	int col = locX;
	
	HRESULT HR = S_OK;
	board[row][col].SetPiece(EMPTY);
	board[row][col].SetColor(NO_PLAYER);

	//board[col][row].SetPiece(EMPTY);
	//board[col][row].SetColor(NO_PLAYER);


	return HR;
}

TFGamePiece* TFBoard::GetPieceAt(int x, int y)
{
	int i = y;
	int j = x;
	
	if (i < 0 || i >= BOARD_DIMENSION ||
		j < 0 || j >= BOARD_DIMENSION)
	{
		//return TFGamePiece();
		return NULL;
	}
	
	return &board[i][j];
}

HRESULT TFBoard::ResetPiecePoints()
{
	HRESULT HR = S_OK;
	for(int i=0; i < BOARD_DIMENSION; i++)
	{
		for(int j=0; j < BOARD_DIMENSION; j++)
		{
			if(board[i][j].GetPiece() == TROOP_PIECE)
				board[i][j].SetPoints(PIECE_POINTS); // 3 points
		}
	}
	return HR;
}


TF_WINNER TFBoard::GameOverTest(){
	TF_WINNER winner = BLUE_WINNER;

	for(int i=0;i<8;i++){
		if(GetPieceAt(i,0)->GetPiece() == FLAG_0 || GetPieceAt(i,0)->GetPiece() == FLAG_1 || GetPieceAt(i,0)->GetPiece() == FLAG_2){
			winner = NO_WINNER;
		}
	}

	if(winner == NO_WINNER){
		winner = RED_WINNER;
		
		for(int i=0;i<8;i++){
			if(GetPieceAt(i,7)->GetPiece() == FLAG_0 || GetPieceAt(i,7)->GetPiece() == FLAG_1 || GetPieceAt(i,7)->GetPiece() == FLAG_2){
				winner = NO_WINNER;
			}
		}
	}

	return winner;
}



